﻿namespace Lilium.LParse

type State<'symbol> =
    abstract member Eof : bool
    abstract member Split :
        ('symbol -> bool)
        -> option<'symbol * State<'symbol>>

module State =

    open Lilium.LParse.Prelude

    let rec fromList list = 
        { new State<'a> with
            member x.Split p =
                match list with
                | s::ss when p s -> Some (s, fromList ss)
                | _ -> None 
            member x.Eof = list.IsEmpty }

    let fromString (str : string) =
        let rec fromString' pos = 
            { new State<char> with
                member x.Split p =
                    if not x.Eof
                        then Some (str.[pos], fromString' (pos + 1))
                        else None 
                member x.Eof = (pos = str.Length) }

        fromString' 0